package org.gg.boom.kernel.validate;


import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.gg.boom.common.model.BaseParam;
import org.gg.boom.kernel.web.CacheParamBodyAdvice;

import java.util.Objects;

public class FieldUniqueValidator implements ConstraintValidator<FieldUnique, Object> {

    @Resource
    FieldUniqueService fieldUniqueService;

    /**
     * 表名称
     */
    private String tableName;

    /**
     * 列名称
     */
    private String columnName;

    /**
     * id字段的名称
     */
    private String idFieldName;

    /**
     * 是否开启逻辑删除校验，默认是关闭的
     */
    private boolean excludeLogicDeleteItems;

    /**
     * 逻辑删除的字段名称
     */
    private String logicDeleteFieldName;

    /**
     * 默认逻辑删除的值
     */
    private String logicDeleteValue;

    @Override
    public void initialize(FieldUnique constraintAnnotation) {
        this.tableName = constraintAnnotation.tableName();
        this.columnName = constraintAnnotation.columnName();
        this.excludeLogicDeleteItems = constraintAnnotation.excludeLogicDeleteItems();
        this.logicDeleteFieldName = constraintAnnotation.logicDeleteFieldName();
        this.logicDeleteValue = constraintAnnotation.logicDeleteValue();
        this.idFieldName = constraintAnnotation.idFieldName();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (Objects.isNull(value)) {
            return true;
        }
        Class<?> group = ValidatorGroup.getValidatorGroup();
        FieldUniqueParam fieldUniqueParam;
        if (BaseParam.edit.class.equals(group)) {
            fieldUniqueParam = buildEditValidateParam(value);
        } else {
            fieldUniqueParam = buildAddValidateParam(value);
        }
        return fieldUniqueService.fieldUnique(fieldUniqueParam);
    }

    private FieldUniqueParam buildAddValidateParam(Object value) {
        return FieldUniqueParam.builder()
                .tableName(tableName)
                .columnName(columnName)
                .value(value)
                .excludeCurrentRecord(Boolean.FALSE)
                .excludeLogicDeleteItems(excludeLogicDeleteItems)
                .logicDeleteFieldName(logicDeleteFieldName)
                .logicDeleteValue(logicDeleteValue)
                .build();
    }

    private FieldUniqueParam buildEditValidateParam(Object value) {
        Dict cacheParam = CacheParamBodyAdvice.getCacheParam();
        String idFieldName = StrUtil.toCamelCase(this.idFieldName);
        return FieldUniqueParam.builder()
                .tableName(tableName)
                .columnName(columnName)
                .value(value)
                .idFieldName(idFieldName)
                .excludeCurrentRecord(Boolean.TRUE)
                .id(cacheParam.getLong(idFieldName))
                .excludeLogicDeleteItems(excludeLogicDeleteItems)
                .logicDeleteFieldName(logicDeleteFieldName)
                .logicDeleteValue(logicDeleteValue)
                .build();
    }
}
